package procsim;

import java.util.*;

public class Bus implements Element{
    private MSignal val;
    private int numOfBits;
    private ArrayList<Sig> listOut = new ArrayList<Sig>();
    private ArrayList<Sig> listIn = new ArrayList<Sig>();
    public Bus(int num){
        numOfBits=num;
        val=new MSignal(numOfBits, 0);
        val.set(MSignal.HIGHZ);
    }
    public Bus(){
        this(16);
    }
    public int getNumOfBits(){
        return numOfBits;
    }
    public Bus put(MSignal sig){
        listIn.add(sig);
        return this;
    }
    public Bus registerSignal(MSignal sig){
        listOut.add(sig);
        return this;
    }
    @Override
    public Bus tick() {
        boolean set = false;
        Iterator iter = listIn.iterator();
        while(iter.hasNext()){
            MSignal sig = (MSignal)iter.next();
            if(sig.get()!=MSignal.HIGHZ){
                val.set(sig.get());
                set = true;
            }
        }
        if(!set) val.set(MSignal.HIGHZ);
        iter = listOut.iterator();
        while(iter.hasNext()){
            set = false;
            MSignal sig = (MSignal)iter.next();
            if(val.get()!=MSignal.HIGHZ){
                sig.set(val);
                set = true;
            }
            if(!set) sig.set(MSignal.HIGHZ);
        }
        return this;
    }
    @Override
    public MSignal result(){
        return val;
    }
    @Override
    public String toString(){
        return ""+val;
    }
    @Override
    public void updateSignal(Sig sig) {
        ArrayList<Sig> newlist = new ArrayList<Sig>();
        boolean changed = false;
        Iterator iter = listIn.iterator();
        while(iter.hasNext()){
            MSignal cur = ((MSignal)iter.next());
            if(cur==sig){
                newlist.add(sig);
                changed = true;
            } else newlist.add(cur);
        }
        listIn = newlist;
        if(changed) tick();
    }
}
